/**
 * This script contains WAPI functions that need to be run in the context of the webpage
 */

/**
 * Auto discovery the webpack object references of instances that contains all functions used by the WAPI
 * functions and creates the Store object.
 */
if (!window.Store || !window.Store.Msg) {
    (function () {
        function getStore(modules) {
            let foundCount = 0;
            let neededObjects = [
                {
                    id: "Store",
                    conditions: (module) => (module.default && module.default.Chat && module.default.Msg) ? module.default : null
                },
                {
                    id: "MediaCollection",
                    conditions: (module) => (module.default && module.default.prototype && (module.default.prototype.processFiles !== undefined || module.default.prototype.processAttachments !== undefined)) ? module.default : null
                },
                {id: "MediaProcess", conditions: (module) => (module.BLOB) ? module : null},
                {id: "Archive", conditions: (module) => (module.setArchive) ? module : null},
                {id: "Block", conditions: (module) => (module.blockContact && module.unblockContact) ? module : null},
                {id: "ChatUtil", conditions: (module) => (module.sendClear) ? module : null},
                {id: "GroupInvite", conditions: (module) => (module.queryGroupInviteCode) ? module : null},
                {id: "Wap", conditions: (module) => (module.createGroup) ? module : null},
                {
                    id: "ServiceWorker",
                    conditions: (module) => (module.default && module.default.killServiceWorker) ? module : null
                },
                {id: "State", conditions: (module) => (module.STATE && module.STREAM) ? module : null},
                {
                    id: "_Presence",
                    conditions: (module) => (module.setPresenceAvailable && module.setPresenceUnavailable) ? module : null
                },
                {
                    id: "WapDelete",
                    conditions: (module) => (module.sendConversationDelete && module.sendConversationDelete.length == 2) ? module : null
                },
                {
                    id: "Conn",
                    conditions: (module) => (module.default && module.default.ref && module.default.refTTL) ? module.default : null
                },
                {
                    id: "WapQuery",
                    conditions: (module) => (module.queryExist) ? module : ((module.default && module.default.queryExist) ? module.default : null)
                },
                {id: "CryptoLib", conditions: (module) => (module.decryptE2EMedia) ? module : null},
                {
                    id: "OpenChat",
                    conditions: (module) => (module.default && module.default.prototype && module.default.prototype.openChat) ? module.default : null
                },
                {
                    id: "UserConstructor",
                    conditions: (module) => (module.default && module.default.prototype && module.default.prototype.isServer && module.default.prototype.isUser) ? module.default : null
                },
                {
                    id: "SendTextMsgToChat",
                    conditions: (module) => (module.sendTextMsgToChat) ? module.sendTextMsgToChat : null
                },
                {id: "ReadSeen", conditions: (module) => (module.sendSeen) ? module : null},
                {id: "sendDelete", conditions: (module) => (module.sendDelete) ? module.sendDelete : null},
                {
                    id: "addAndSendMsgToChat",
                    conditions: (module) => (module.addAndSendMsgToChat) ? module.addAndSendMsgToChat : null
                },
                {id: "sendMsgToChat", conditions: (module) => (module.sendMsgToChat) ? module.sendMsgToChat : null},
                {id: "Catalog", conditions: (module) => (module.Catalog) ? module.Catalog : null},
                {
                    id: "bp",
                    conditions: (module) => (module.default && module.default.toString && module.default.toString().includes('bp_unknown_version')) ? module.default : null
                },
                {
                    id: "MsgKey",
                    conditions: (module) => (module.default && module.default.toString && module.default.toString().includes('MsgKey error: obj is null/undefined')) ? module.default : null
                },
                {
                    id: "Parser",
                    conditions: (module) => (module.convertToTextWithoutSpecialEmojis) ? module.default : null
                },
                {
                    id: "Builders",
                    conditions: (module) => (module.TemplateMessage && module.HydratedFourRowTemplate) ? module : null
                },
                {id: "Me", conditions: (module) => (module.PLATFORMS && module.Conn) ? module.default : null},
                {id: "CallUtils", conditions: (module) => (module.sendCallEnd && module.parseCall) ? module : null},
                {
                    id: "Identity",
                    conditions: (module) => (module.queryIdentity && module.updateIdentity) ? module : null
                },
                {id: "MyStatus", conditions: (module) => (module.getStatus && module.setMyStatus) ? module : null},
                {
                    id: "ChatStates",
                    conditions: (module) => (module.sendChatStatePaused && module.sendChatStateRecording && module.sendChatStateComposing) ? module : null
                },
                {
                    id: "GroupActions",
                    conditions: (module) => (module.sendExitGroup && module.localExitGroup) ? module : null
                },
                {
                    id: "Features",
                    conditions: (module) => (module.FEATURE_CHANGE_EVENT && module.features) ? module : null
                },
                {
                    id: "MessageUtils",
                    conditions: (module) => (module.storeMessages && module.appendMessage) ? module : null
                },
                {
                    id: "WebMessageInfo",
                    conditions: (module) => (module.WebMessageInfo && module.WebFeatures) ? module.WebMessageInfo : null
                },
                {
                    id: "createMessageKey",
                    conditions: (module) => (module.createMessageKey && module.createDeviceSentMessage) ? module.createMessageKey : null
                },
                {
                    id: "Participants",
                    conditions: (module) => (module.addParticipants && module.removeParticipants && module.promoteParticipants && module.demoteParticipants) ? module : null
                },
                {
                    id: "WidFactory",
                    conditions: (module) => (module.isWidlike && module.createWid && module.createWidFromWidLike) ? module : null
                },
                {
                    id: "Base",
                    conditions: (module) => (module.setSubProtocol && module.binSend && module.actionNode) ? module : null
                },
                {
                    id: "Versions",
                    conditions: (module) => (module.loadProtoVersions && module.default["15"] && module.default["16"] && module.default["17"]) ? module : null
                },
                {
                    id: "Sticker",
                    conditions: (module) => (module.default && module.default.Sticker) ? module.default.Sticker : null
                },
                {
                    id: "MediaUpload",
                    conditions: (module) => (module.default && module.default.mediaUpload) ? module.default : null
                },
                {
                    id: "UploadUtils",
                    conditions: (module) => (module.default && module.default.encryptAndUpload) ? module.default : null
                }
            ];
            for (let idx in modules) {
                if ((typeof modules[idx] === "object") && (modules[idx] !== null)) {
                    neededObjects.forEach((needObj) => {
                        if (!needObj.conditions || needObj.foundedModule)
                            return;
                        let neededModule = needObj.conditions(modules[idx]);
                        if (neededModule !== null) {
                            foundCount++;
                            needObj.foundedModule = neededModule;
                        }
                    });

                    if (foundCount == neededObjects.length) {
                        break;
                    }
                }
            }
            let neededStore = neededObjects.find((needObj) => needObj.id === "Store");
            window.Store = neededStore.foundedModule ? neededStore.foundedModule : {};
            neededObjects.splice(neededObjects.indexOf(neededStore), 1);
            neededObjects.forEach((needObj) => {
                if (needObj.foundedModule) {
                    window.Store[needObj.id] = needObj.foundedModule;
                }
            });
            window.Store.Chat.modelClass.prototype.sendMessage = function (e) {
                window.Store.SendTextMsgToChat(this, ...arguments);
            }
            return window.Store;
        }

        const parasite = `parasite${Date.now()}`
        // webpackJsonp([], { [parasite]: (x, y, z) => getStore(z) }, [parasite]);
        if (typeof webpackJsonp === 'function') webpackJsonp([], {[parasite]: (x, y, z) => getStore(z)}, [parasite]);
        else webpackChunkwhatsapp_web_client.push([[parasite], {}, function (o, e, t) {
            let modules = [];
            for (let idx in o.m) {
                modules.push(o(idx));
            }
            getStore(modules);
        }]);
    })();
}

window.WAPI = {};
window._WAPI = {};

window.WAPI._serializeRawObj = (obj) => {
    if (obj && obj.toJSON) {
        return obj.toJSON();
    }
    return {}
};

/**
 * Serializes a chat object
 *
 * @param rawChat Chat object
 * @returns {{}}
 */

window.WAPI._serializeChatObj = (obj) => {
    if (obj == undefined) {
        return null;
    }
    return Object.assign(window.WAPI._serializeRawObj(obj), {
        id: obj.id._serialized,
        kind: obj.kind,
        isGroup: obj.isGroup,
        formattedTitle: obj.formattedTitle,
        contact: obj['contact'] ? window.WAPI._serializeContactObj(obj['contact']) : null,
        groupMetadata: obj["groupMetadata"] ? window.WAPI._serializeRawObj(obj["groupMetadata"]) : null,
        presence: obj["presence"] ? window.WAPI._serializeRawObj(obj["presence"]) : null,
        msgs: null
    });
};

window.WAPI._serializeContactObj = (obj) => {
    if (obj == undefined) {
        return null;
    }
    return Object.assign(window.WAPI._serializeRawObj(obj), {
        id: obj.id._serialized,
        formattedName: obj.formattedName,
        isHighLevelVerified: obj.isHighLevelVerified,
        isMe: obj.isMe,
        isMyContact: obj.isMyContact,
        isPSA: obj.isPSA,
        isUser: obj.isUser,
        isVerified: obj.isVerified,
        isWAContact: obj.isWAContact,
        profilePicThumbObj: obj.profilePicThumb ? WAPI._serializeProfilePicThumb(obj.profilePicThumb) : {},
        statusMute: obj.statusMute,
        msgs: null
    });
};


window.WAPI._serializeMessageObj = (obj) => {
    if (obj == undefined) {
        return null;
    }
    const _chat = obj['chat'] ? WAPI._serializeChatObj(obj['chat']) : {};
    if (obj.quotedMsg) obj.quotedMsgObj();
    return Object.assign(window.WAPI._serializeRawObj(obj), {
        id: obj.id._serialized,
        from: obj.from._serialized,
        quotedParticipant: obj.quotedParticipant ? obj.quotedParticipant._serialized ? obj.quotedParticipant._serialized : undefined : undefined,
        author: obj.author ? obj.author._serialized ? obj.author._serialized : undefined : undefined,
        chatId: obj.chatId ? obj.chatId._serialized ? obj.chatId._serialized : undefined : undefined,
        to: obj.to ? obj.to._serialized ? obj.to._serialized : undefined : undefined,
        fromMe: obj.id.fromMe,
        sender: obj["senderObj"] ? WAPI._serializeContactObj(obj["senderObj"]) : null,
        timestamp: obj["t"],
        content: obj["body"],
        isGroupMsg: obj.isGroupMsg,
        isLink: obj.isLink,
        isMMS: obj.isMMS,
        isMedia: obj.isMedia,
        isNotification: obj.isNotification,
        isPSA: obj.isPSA,
        type: obj.type,
        chat: _chat,
        isOnline: _chat.isOnline,
        lastSeen: _chat.lastSeen,
        chatId: obj.id.remote,
        quotedMsgObj: WAPI._serializeMessageObj(obj['_quotedMsgObj']),
        mediaData: window.WAPI._serializeRawObj(obj['mediaData']),
        reply: body => window.WAPI.reply(_chat.id._serialized, body, obj)
    });
};

window.WAPI._serializeNumberStatusObj = (obj) => {
    if (obj == undefined) {
        return null;
    }

    return Object.assign({}, {
        id: obj.jid,
        status: obj.status,
        isBusiness: (obj.biz === true),
        canReceiveMessage: (obj.status === 200)
    });
};

window.WAPI._serializeProfilePicThumb = (obj) => {
    if (obj == undefined) {
        return null;
    }

    return Object.assign({}, {
        eurl: obj.eurl,
        id: obj.id,
        img: obj.img,
        imgFull: obj.imgFull,
        raw: obj.raw,
        tag: obj.tag
    });
}


window.WAPI.downloadFile = async function (url) {
    return await new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest();
        xhr.onload = function () {
            if (xhr.readyState == 4) {
                if (xhr.status == 200) {
                    let reader = new FileReader();
                    reader.readAsDataURL(xhr.response);
                    reader.onload = function (e) {
                        resolve(reader.result.substr(reader.result.indexOf(',') + 1))
                    };
                } else {
                    console.error(xhr.statusText);
                }
            } else {
                console.log(err);
                resolve(false);
            }
        };

        xhr.open("GET", url, true);
        xhr.responseType = 'blob';
        xhr.send(null);
    })
};

/**
 * Sends product with image to chat
 * @param imgBase64 Base64 image data
 * @param chatid string the id of the chat that you want to send this product to
 * @param caption string the caption you want to add to this message
 * @param bizNumber string the @c.us number of the business account from which you want to grab the product
 * @param productId string the id of the product within the main catalog of the aforementioned business
 * @returns
 */
window.WAPI.sendImageWithProduct = async function (imgBase64, chatid, caption, bizNumber, productId) {
    await WAPI.refreshBusinessProfileProducts();
    return await Store.Catalog.findCarouselCatalog(bizNumber).then(async cat => {
        if (cat && cat[0]) {
            const product = cat[0].productCollection.get(productId);
            const temp = {
                productMsgOptions: {
                    businessOwnerJid: product.catalogWid.toString({
                        legacy: !0
                    }),
                    productId: product.id.toString(),
                    url: product.url,
                    productImageCount: product.productImageCollection.length,
                    title: product.name,
                    description: product.description,
                    currencyCode: product.currency,
                    priceAmount1000: product.priceAmount1000,
                    type: "product"
                },
                caption
            }

            // var idUser = new Store.WidFactory.createWid(chatid);

            return Store.Chat.find(chatid).then(async (chat) => {
                var mediaBlob = window.WAPI.base64ImageToFile(imgBase64, "filename.jpg");
                // var mc = new Store.MediaCollection(chat);
                // mc.processFiles([mediaBlob], chat, 1)
                return await window.WAPI.procFiles(chat, mediaBlob).then(async mc => {
                    var media = mc.models[0];
                    Object.entries(temp.productMsgOptions).map(([k, v]) => media.mediaPrep._mediaData[k] = v)
                    await media.mediaPrep.sendToChat(chat, temp);
                    return chat.lastReceivedKey._serialized;
                });
            });
        }
    })
}

window.WAPI.base64ImageToFile = function (b64Data, filename) {
    var arr = b64Data.split(',');
    var mime = arr[0].match(/:(.*?);/)[1];
    var bstr = window.Base64 ? window.Base64.atob(arr[1]) : atob(arr[1]);
    var n = bstr.length;
    var u8arr = new Uint8Array(n);

    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }

    return new File([u8arr], filename, {type: mime});
};

window.WAPI.onChatState = function () {
    return false;
}

/**
 * If you're using WAPI.js outside of open-wa: https://github.com/open-wa/wa-automate-nodejs/ then you can use the following code to enable the locked features above if you've got a license keu.
 *
 * THIS WILL NOT WORK OUT OF THE BOX. YOU WILL NEED TO DISAVLE CONTENT SECURITY POLICY (WHICH IS HIGHLY DISCOURAGED AND THE MAINTAINERS OF THIS CODE ASSUME NO RESPONSIBILITY FOR AY SECURITY VUNERABILITIES RESULTING IN DISABLING CSP)
 *
 * This is meant to act as an example of how to enable new features in wapi.js. You should implement this outside of the WA WEB browser context.
 *
 * Please use google to find out how to disable CSP. You can also use this extension: https://chrome.google.com/webstore/detail/disable-content-security/ieelmcmcagommplceebfedjlakkhpden/related?hl=en
 */
window.WAPI.addLicenseKey = async function (key) {
    const pkgR = await fetch('https://raw.githubusercontent.com/open-wa/wa-automate-nodejs/master/package.json');
    const pkg = await pkgR.json();
    const body = JSON.stringify({
        number: Store.Me.me._serialized,
        key
    });
    const r = await fetch(pkg.licenseCheckUrl, {
        method: 'POST',
        mode: 'cors',
        cache: 'no-cache',
        headers: {
            'Content-Type': 'application/json'
        },
        credentials: 'same-origin',
        redirect: 'follow',
        referrerPolicy: 'no-referrer',
        body
    })
    const x = await r.text()
    return eval(x);
}

//切换聊天对象的时候通知electron
var currentChatId = null;

//作为一个页面和electron通信的基础轮询，包括聊天对象的改变，未读消息的处理
getCurrentChatId = function () {
    Store.Chat._models.map(md => {
        if (md.__x_active === true) {
            var currentChatId2 = md.__x_id.user + "@" + md.__x_id.server;
            if (currentChatId === null || currentChatId !== currentChatId2) {
                currentChatId = currentChatId2;
                // document.getElementById("main").childNodes[4].remove();
                // document.getElementById("main").childNodes[5].remove();
                // document.getElementById("main").childNodes[6].remove();
                //发送通知
                console.log("getCurrentChatId===",md)

                window.fromWebToElectron("chatChange", {
                    "loginAccount": window.WAPI.getMe().wid,
                    "chatUser": currentChatId,
                    "isGroup": md.isGroup,
                    "viewId": getViewId()
                });
            }
        }
    })

    if(me!==null){
        window.WAPI.getAllUnreadMessages().then(data => {
            window.fromWebToElectron("commonNotify", {
                "viewId": getViewId(),
                "unReadMsg": data.length
            });
        })
    }
    setTimeout(getCurrentChatId, 500)
}
getCurrentChatId();
//监听消息发送
const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay))
allNewMessagesListener = function () {
    window.Store.Msg.on('add', (newMessage) => {
        if (newMessage && newMessage.isNewMsg) {
            let message = window.WAPI.processMessageObj(newMessage, true, false);
            let fomartedMsg = {
                "contentType": newMessage.mimetype,
                "sendDateTime": newMessage.t,
                "textTypeMessage": newMessage.body,
                "seatSendFlag": newMessage.self,
                "userType": newMessage.isGroupMsg,
                "from": newMessage.from._serialized,
                "to": newMessage.to._serialized,
                "senderNickName": message.sender.formattedName,
                "senderAccount": message.sender.id
            };
            if (typeof fomartedMsg.contentType !== "undefined" && (fomartedMsg.contentType.indexOf("image") !== -1)) {
                window.WAPI.downloadFile(newMessage.mediaObject.mediaBlob._url).then(x => {
                    fomartedMsg.textTypeMessage = x;
                    newMsgHandler(message, newMessage, fomartedMsg)
                })
            } else {
                newMsgHandler(message, newMessage, fomartedMsg)
            }
        }
    });
}

newMsgHandler = function (message, newMessage, fomartedMsg,) {

    console.log("自动回复开关状态", isAutoReply, fomartedMsg);
    window.fromWebToElectron("chatMessage", fomartedMsg);


    if (!isAutoReply) {
        return;
    }

    if (message) {
        if (message.type === "chat" && message.fromMe === false) {
            // sleep(2000).then(() => window.WAPI.sendMessage(message.chat.id, "hello,这个是自动回复给 " + message.chat.formattedTitle + " 的消息:" + message.body));
            let item = {}
            for (let i = 0; i < autoList.length; i++) {
                if (autoList[i].matchMode === 1) {
                    if (newMessage.body.toUpperCase().search(autoList[i].keyword.toUpperCase()) !== -1) {
                        item = autoList[i]
                    }
                } else {
                    if (newMessage.body.toUpperCase() === autoList[i].keyword.toUpperCase()) {
                        item = autoList[i]
                    }
                }

            }

            if (item.replyMode === 1) {
                for (let i = 0; i < item.contents.length; i++) {
                    sleep(item.replyMode * 1000).then(() => window.WAPI.sendMessage(message.chat.id, item.contents[i]));
                }
            } else {
                sleep(item.replyMode * 1000).then(() => window.WAPI.sendMessage(message.chat.id, item.contents[index(0, item.contents.length - 1)]));
            }
        }
    }
}


let index = function (min, max) {
    return Math.floor(Math.random() * (max - min)) + min
}

allNewMessagesListener();







